import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;


/**
 * The class that does all the communication with the database, and checks existing data
 *
 */
public class DataAbstractionLayer {
	
	/** the singleton object of the DataAbtractionLayer */
	private static DataAbstractionLayer singleton;
	
	/** The following ArrayLists hold a local copy of the what has been loaded
	 * into the database, this allows us to check for existing entries
	 * without the overhead of an SQL query */
	private ArrayList<Airline> airlines = new ArrayList<Airline>();
	
	private ArrayList<Airport> airports = new ArrayList<Airport>();
	
	private ArrayList<Employee> employees = new ArrayList<Employee>();
	
	private ArrayList<Customer> customers = new ArrayList<Customer>();
	
	private ArrayList<FlightSegment> flightSegments = new ArrayList<FlightSegment>();
	
	private ArrayList<FlightReservation> reservations = new ArrayList<FlightReservation>();
	
	private ArrayList<FlightDate> flightDates = new ArrayList<FlightDate>();
	
	private ArrayList<Passenger> passengers = new ArrayList<Passenger>();
	
	private ArrayList<PlaneModel> planeModels = new ArrayList<PlaneModel>();
	
	private ArrayList<Seat> seats = new ArrayList<Seat>();
	
	/** The database connection */
	private Connection conn;
	
	/** The prepared statements used to add entries to the database */
	private PreparedStatement addEmployeeStatement;
	
	private PreparedStatement addAirlineStatement;
	
	private PreparedStatement addAirportStatement;
	
	private PreparedStatement addCustomerStatement;
	
	private PreparedStatement addFlightSegmentStatment;
	
	private PreparedStatement addFlightReservationStatement;
	
	private PreparedStatement addReservationStatement;
	
	private PreparedStatement addFlightDateStatement;
	
	private PreparedStatement addPassengerStatement;
	
	private PreparedStatement addPlaneModelStatement;
	
	private PreparedStatement updateSeatStatement;
	
	/** Used to find the generated key of an entry.  Needed because PostgreSQL driver doesn't
	 * support returned auto generated keys */
	private PreparedStatement findEmployeeKeyStatement;
	
	private PreparedStatement findAirlineKeyStatement;
	
	private PreparedStatement findAirportKeyStatement;
	
	private PreparedStatement findCustomerKeyStatement;
	
	private PreparedStatement findFlightSegmentKeyStatment;
	
	private PreparedStatement findReservationKeyStatement;
	
	private PreparedStatement findFlightDateKeyStatement;
	
	private PreparedStatement findPassengerKeyStatement;
	
	private PreparedStatement findPlaneModelKeyStatement;
	
	private final String sqlFindEmployeeKey = 
		"SELECT EmployeeID " +
		"FROM Employees " + 
		"WHERE FirstName = ? AND LastName = ? AND isEmployed = ? AND isBookingAgent = ?";
	
	private final String sqlFindAirlineKey = 
		"SELECT AirlineID " + 
		"FROM Airlines " + 
		"WHERE Code = ? AND Name = ? ";
	
	private final String sqlFindAirportKey = 
		"SELECT AirportID " + 
		"FROM Airports " + 
		"WHERE Code = ? AND City = ?";
	
	private final String sqlFindCustomerKey = 
		"SELECT CustomerID " + 
		"FROM Customers " + 
		"WHERE FirstName = ? AND LastName = ?  AND Address = ? AND CreditCard = ?";
	
	private final String sqlFindFlightSegmentID = 
		"SELECT FlightSegmentID " + 
		"FROM FlightSegments " + 
		"WHERE FlightNo = ? AND Price = ? AND DepartureTime = ? AND ArrivalTime= ? AND FromAirportID = ? " + 
		"AND ToAirportID = ? AND  AirlineID = ? AND PlaneModelID = ? ";
	
	private final String sqlFindReservationKey = 
		"SELECT ReservationID " + 
		"FROM Reservations " + 
		"WHERE BookingAgentID = ? AND CustomerID = ? ";
	
	private final String sqlFindFlightDateKey = 
		"SELECT FlightDateID " + 
		"FROM FlightDates " + 
		"WHERE FlightSegmentID = ? AND DepartureDate = ?";
	
	private final String sqlFindPassengerKey = 
		"SELECT PassengerID " + 
		"FROM Passengers " + 
		"WHERE FirstName = ? AND LastName = ? AND PassportNo = ? AND PassportCountry = ?";
	
	private final String sqlFindPlaneModelKey = 
		"SELECT PlaneModelID " + 
		"FROM PlaneModels " + 
		"WHERE Model = ? AND NumRows = ? AND NumCols = ? ";
	
	private final String sqlAddEmployee = 
		"INSERT INTO Employees(FirstName, LastName, isEmployed, isBookingAgent) " +
		"VALUES(?,?,?,?)";
	
	private final int FIRSTNAMEINDEX = 1, LASTNAMEINDEX = 2, 
		ISEMPLOYEDINDEX = 3, ISBOOKINGAGENTINDEX = 4;
	
	private final String sqlAddAirline = 
		"INSERT INTO Airlines(Code, Name) " +
		"VALUES(?,?)";
	
	private final int CODEINDEX = 1, NAMEINDEX = 2;
	
	private final String sqlAddAirport = 
		"INSERT INTO Airports(Code, City) " +
		"VALUES(?,?)";
	
	private final int CITYINDEX = 2;
	
	private final String sqlAddCustomer = 
		"INSERT INTO Customers(FirstName, LastName, Address, CreditCard) " +
		"VALUES(?,?,?,?)";
	
	private final int ADDRESSINDEX = 3, CREDITCARDINDEX = 4;
	
	private final String sqlAddFlightSegment = 
		"INSERT INTO FlightSegments(FlightNo, Price, DepartureTime, ArrivalTime, FromAirportID, ToAirportID, AirlineID, PlaneModelID) " +
		"VALUES(?,?,?,?,?,?,?,?)";
	
	private final int FLIGHTNOINDEX = 1, PRICEINDEX = 2, DEPARTURETIMEINDEX = 3, ARRIVALTIMEINDEX = 4, 
		FROMAIRPORTINDEX = 5, TOAIRPORTIDINDEX = 6, AIRLINEIDINDEX = 7, PLANEMODELIDINDEX = 8;
	
	private final String sqlAddReservation = 
		"INSERT INTO Reservations(BookingAgentID, CustomerID) " +
		"VALUES(?,?)";
	
	private final int BOOKINGAGENTIDINDEX = 1, CUSTOMERIDINDEX = 2;
	
	private final String sqlAddFlightReservation = 
		"INSERT INTO FlightReservations(ReservationID, TotalPrice) " +
		"VALUES(?,?)";
	
	private final int RESERVATIONIDINDEX = 1, TOTALPRICEINDEX = 2;  
	
	private final String sqlAddFlightDate = 
		"INSERT INTO FlightDates(FlightSegmentID, DepartureDate) " +
		"VALUES(?,?)";
	
	private final int FLIGHTSEGMENTIDINDEX = 1, DEPARTUREDATEINDEX = 2;
	
	private final String sqlAddPassenger = 
		"INSERT INTO Passengers(FirstName, LastName, PassportNo, PassportCountry) " +
		"VALUES(?,?,?,?)";
	
	private final int PASSPORTNOINDEX = 3, PASSPORTCOUNTRYINDEX = 4; 
	
	private final String sqlAddPlaneModel = 
		"INSERT INTO PlaneModels(Model, NumRows, NumCols) " +
		"VALUES(?,?,?)";
	
	private final int MODELINDEX = 1, NUMROWSINDEX = 2, NUMCOLSINDEX = 3;
	
	private final String sqlUpdateSeat = 
		"UPDATE Seats " +
		"SET ReservationID = ?, PassengerID = ? " + 
		"WHERE FlightDateID = ? AND SeatRow = ? AND SeatCol = ?";
	
	private final int PASSENGERIDINDEX = 2, FLIGHTDATEIDINDEX = 3, SEATROWINDEX = 4, SEATCOLINDEX = 5;
	
	
	private DataAbstractionLayer() {
		try {
			Class.forName ("org.postgresql.Driver");
			conn = DriverManager.getConnection("jdbc:postgresql://dbserv.csc.uvic.ca/team11", "mwalts", "fakepassfun");
			
			//do own commits, for speed
			conn.setAutoCommit(false);
			
			initPreparedStatments();
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Initialises the PreparedStatments so that they can be used to add and update the database.
	 * All insert statements will return generated keys
	 * @throws SQLException if there  is a problem with the connection in conn or an error with one of the sql strings
	 */
	private void initPreparedStatments() throws SQLException {
		addEmployeeStatement = conn.prepareStatement(sqlAddEmployee);
		addAirlineStatement = conn.prepareStatement(sqlAddAirline);
		addAirportStatement = conn.prepareStatement(sqlAddAirport);
		addCustomerStatement = conn.prepareStatement(sqlAddCustomer);
		addFlightSegmentStatment = conn.prepareStatement(sqlAddFlightSegment);
		addReservationStatement = conn.prepareStatement(sqlAddReservation);
		addFlightReservationStatement = conn.prepareStatement(sqlAddFlightReservation);
		addFlightDateStatement = conn.prepareStatement(sqlAddFlightDate);
		addPassengerStatement = conn.prepareStatement(sqlAddPassenger);
		addPlaneModelStatement = conn.prepareStatement(sqlAddPlaneModel);
		updateSeatStatement = conn.prepareStatement(sqlUpdateSeat);
		
		findEmployeeKeyStatement = conn.prepareStatement(sqlFindEmployeeKey);
		findAirlineKeyStatement = conn.prepareStatement(sqlFindAirlineKey);
		findAirportKeyStatement = conn.prepareStatement(sqlFindAirportKey);
		findCustomerKeyStatement = conn.prepareStatement(sqlFindCustomerKey);
		findFlightSegmentKeyStatment = conn.prepareStatement(sqlFindFlightSegmentID);
		findReservationKeyStatement = conn.prepareStatement(sqlFindReservationKey);
		findFlightDateKeyStatement = conn.prepareStatement(sqlFindFlightDateKey);
		findPassengerKeyStatement = conn.prepareStatement(sqlFindPassengerKey);
		findPlaneModelKeyStatement = conn.prepareStatement(sqlFindPlaneModelKey);
		
	}
	
	/**
	 * Gets the current instance of the data abstraction layer
	 * @return the current instance of the data abstraction layer
	 */
	public static DataAbstractionLayer getInstance() {

		if(singleton == null) singleton = new DataAbstractionLayer();
		
		return singleton;
	}
	
	public void addEmployee(Employee addMe) {
		int curIndex = employees.indexOf(addMe);
		
		if(curIndex != -1) {
			return;
		}
		
		try{
			addEmployeeStatement.setString(FIRSTNAMEINDEX, addMe.getFirstName());
			addEmployeeStatement.setString(LASTNAMEINDEX, addMe.getLastName());
			addEmployeeStatement.setBoolean(ISEMPLOYEDINDEX, addMe.isEmployed());
			addEmployeeStatement.setBoolean(ISBOOKINGAGENTINDEX, addMe.isBookingAgent());
			
			findEmployeeKeyStatement.setString(FIRSTNAMEINDEX, addMe.getFirstName());
			findEmployeeKeyStatement.setString(LASTNAMEINDEX, addMe.getLastName());
			findEmployeeKeyStatement.setBoolean(ISEMPLOYEDINDEX, addMe.isEmployed());
			findEmployeeKeyStatement.setBoolean(ISBOOKINGAGENTINDEX, addMe.isBookingAgent());
			
			addMe.setEmployeeID(runInsertPrepAndGetKey(addEmployeeStatement, findEmployeeKeyStatement));
			
			employees.add(addMe);
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
	}
	
	
	/**
	 * Adds the airline to the database and datalayer, if it does not already exist
	 * @param addMe The Airline to add
	 */
	public Airline addAirline(Airline addMe) {
		
		int curIndex = airlines.indexOf(addMe);
		
		//if the airline already exists, don't add it again
		if(curIndex != -1){
			return airlines.get(curIndex);
		}
		
		try {
			
			addAirlineStatement.setString(CODEINDEX, addMe.getCode());
			addAirlineStatement.setString(NAMEINDEX, addMe.getName());
			
			findAirlineKeyStatement.setString(CODEINDEX, addMe.getCode());
			findAirlineKeyStatement.setString(NAMEINDEX, addMe.getName());
			
			addMe.setAirlineID(runInsertPrepAndGetKey(addAirlineStatement, findAirlineKeyStatement));
			
			//now add it to the list
			airlines.add(addMe);
			
		}catch (SQLException e) {
			e.printStackTrace();
		}
		
		return addMe;
		
	}
	
	public Customer addCustomer(Customer addMe) {
		int curIndex = customers.indexOf(addMe);
		
		if(curIndex != -1) {
			return customers.get(curIndex);
		}
		
		try{
			addCustomerStatement.setString(FIRSTNAMEINDEX, addMe.getFirstName());
			addCustomerStatement.setString(LASTNAMEINDEX, addMe.getLastName());
			addCustomerStatement.setString(ADDRESSINDEX, addMe.getAddress());
			addCustomerStatement.setString(CREDITCARDINDEX, addMe.getCreditCard());
			
			findCustomerKeyStatement.setString(FIRSTNAMEINDEX, addMe.getFirstName());
			findCustomerKeyStatement.setString(LASTNAMEINDEX, addMe.getLastName());
			findCustomerKeyStatement.setString(ADDRESSINDEX, addMe.getAddress());
			findCustomerKeyStatement.setString(CREDITCARDINDEX, addMe.getCreditCard());
			
			addMe.setCustomerID(runInsertPrepAndGetKey(addCustomerStatement, findCustomerKeyStatement));
			
			customers.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	public FlightSegment addFlightSegment(FlightSegment addMe) throws Exception {
		int curIndex = flightSegments.indexOf(addMe);
		
		if(curIndex != -1) {
			FlightSegment retMe = flightSegments.get(curIndex);
			return retMe;
		}
		
		//ensure that there is a proper customer and employee associated with this reservation
		if(!addMe.getFromAirport().isIDSet() || !addMe.getToAirport().isIDSet() || 
				!addMe.getAirline().isIDSet() || !addMe.getPlaneModel().isIdSet()) {
			throw new Exception("Id not set on required field");
		}
		
		try{
			addFlightSegmentStatment.setString(FLIGHTNOINDEX, addMe.getFlightNo());
			addFlightSegmentStatment.setDouble(PRICEINDEX, addMe.getPrice());
			addFlightSegmentStatment.setTime(DEPARTURETIMEINDEX, addMe.getDepartureTime());
			addFlightSegmentStatment.setTime(ARRIVALTIMEINDEX, addMe.getArrivalTime());
			
			addFlightSegmentStatment.setInt(FROMAIRPORTINDEX, (int)addMe.getFromAirport().getAirportID());
			addFlightSegmentStatment.setInt(TOAIRPORTIDINDEX, (int)addMe.getToAirport().getAirportID());
			addFlightSegmentStatment.setInt(AIRLINEIDINDEX, (int)addMe.getAirline().getAirlineID());
			addFlightSegmentStatment.setInt(PLANEMODELIDINDEX, (int)addMe.getPlaneModel().getPlaneModelID());
			
			findFlightSegmentKeyStatment.setString(FLIGHTNOINDEX, addMe.getFlightNo());
			findFlightSegmentKeyStatment.setDouble(PRICEINDEX, addMe.getPrice());
			findFlightSegmentKeyStatment.setTime(DEPARTURETIMEINDEX, addMe.getDepartureTime());
			findFlightSegmentKeyStatment.setTime(ARRIVALTIMEINDEX, addMe.getArrivalTime());
			
			findFlightSegmentKeyStatment.setInt(FROMAIRPORTINDEX, (int)addMe.getFromAirport().getAirportID());
			findFlightSegmentKeyStatment.setInt(TOAIRPORTIDINDEX, (int)addMe.getToAirport().getAirportID());
			findFlightSegmentKeyStatment.setInt(AIRLINEIDINDEX, (int)addMe.getAirline().getAirlineID());
			findFlightSegmentKeyStatment.setInt(PLANEMODELIDINDEX, (int)addMe.getPlaneModel().getPlaneModelID());
			
			addMe.setFlightSegmentID(runInsertPrepAndGetKey(addFlightSegmentStatment, findFlightSegmentKeyStatment));
			
			flightSegments.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	public FlightReservation addReservation(FlightReservation addMe) throws Exception{
		
		int curIndex = reservations.indexOf(addMe);
		
		if(curIndex != -1) {
			return reservations.get(curIndex);
		}
	
		//ensure that there is a proper customer and employee associated with this reservation
		if(!addMe.getBookingAgent().isIdSet() || !addMe.getCustomer().isIdSet()) {
			throw new Exception("Id not set on required field");
		}
		
		try{
			
			//first add the reservation entry
			addReservationStatement.setInt(BOOKINGAGENTIDINDEX, (int)addMe.getBookingAgent().getEmployeeID());
			addReservationStatement.setInt(CUSTOMERIDINDEX, (int)addMe.getCustomer().getCustomerID());
			
			findReservationKeyStatement.setInt(BOOKINGAGENTIDINDEX, (int)addMe.getBookingAgent().getEmployeeID());
			findReservationKeyStatement.setInt(CUSTOMERIDINDEX, (int)addMe.getCustomer().getCustomerID());
			
			addMe.setReservationID(runInsertPrepAndGetKey(addReservationStatement, findReservationKeyStatement));
			
			//now add the flight reservation
			addFlightReservationStatement.setInt(RESERVATIONIDINDEX, (int)addMe.getReservationID());
			addFlightReservationStatement.setDouble(TOTALPRICEINDEX, addMe.getTotalPrice());
			
			addFlightReservationStatement.executeUpdate();
			
			reservations.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
		
	}
	
	public FlightDate addFlightDate(FlightDate addMe) throws Exception {
		int curIndex = flightDates.indexOf(addMe);
		
		if(curIndex != -1) {
			return flightDates.get(curIndex);
		}
		
		//ensure that there is a proper FlightSegment
		if(!addMe.getFlightSegment().isIdSet()) {
			throw new Exception("Id not set on required field");
		}
		
		try{
			addFlightDateStatement.setInt(FLIGHTSEGMENTIDINDEX, (int)addMe.getFlightSegment().getFlightSegmentID());
			addFlightDateStatement.setDate(DEPARTUREDATEINDEX, addMe.getDepartureDate());
			
			findFlightDateKeyStatement.setInt(FLIGHTSEGMENTIDINDEX, (int)addMe.getFlightSegment().getFlightSegmentID());
			findFlightDateKeyStatement.setDate(DEPARTUREDATEINDEX, addMe.getDepartureDate());
			
			
			addMe.setFlightDateID(runInsertPrepAndGetKey(addFlightDateStatement, findFlightDateKeyStatement));
			
			flightDates.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	public Passenger addPassenger(Passenger addMe) {
		int curIndex = passengers.indexOf(addMe);
		
		if(curIndex != -1) {
			return passengers.get(curIndex);
		}
		
		try{
			addPassengerStatement.setString(FIRSTNAMEINDEX, addMe.getFirstName());
			addPassengerStatement.setString(LASTNAMEINDEX, addMe.getLastName());
			addPassengerStatement.setString(PASSPORTNOINDEX, addMe.getPassportNo());
			addPassengerStatement.setString(PASSPORTCOUNTRYINDEX, addMe.getPassportCountry());
			
			findPassengerKeyStatement.setString(FIRSTNAMEINDEX, addMe.getFirstName());
			findPassengerKeyStatement.setString(LASTNAMEINDEX, addMe.getLastName());
			findPassengerKeyStatement.setString(PASSPORTNOINDEX, addMe.getPassportNo());
			findPassengerKeyStatement.setString(PASSPORTCOUNTRYINDEX, addMe.getPassportCountry());
			
			addMe.setPassengerID(runInsertPrepAndGetKey(addPassengerStatement, findPassengerKeyStatement));
			
			passengers.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	public PlaneModel addPlaneModel(PlaneModel addMe) {
		int curIndex = planeModels.indexOf(addMe);
		
		if(curIndex != -1) {
			return planeModels.get(curIndex);
		}
		
		try{
			addPlaneModelStatement.setString(MODELINDEX, addMe.getModel());
			addPlaneModelStatement.setInt(NUMROWSINDEX, addMe.getNumRows());
			addPlaneModelStatement.setInt(NUMCOLSINDEX, addMe.getNumCols());
			
			findPlaneModelKeyStatement.setString(MODELINDEX, addMe.getModel());
			findPlaneModelKeyStatement.setInt(NUMROWSINDEX, addMe.getNumRows());
			findPlaneModelKeyStatement.setInt(NUMCOLSINDEX, addMe.getNumCols());
			
			addMe.setPlaneModelID(runInsertPrepAndGetKey(addPlaneModelStatement, findPlaneModelKeyStatement));
			
			planeModels.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	public Airport addAirport(Airport addMe) {
		int curIndex = airports.indexOf(addMe);
		
		if(curIndex != -1) {
			return airports.get(curIndex);
		}
		
		try{
			addAirportStatement.setString(CODEINDEX, addMe.getCode());
			addAirportStatement.setString(CITYINDEX, addMe.getCity());
			
			findAirportKeyStatement.setString(CODEINDEX, addMe.getCode());
			findAirportKeyStatement.setString(CITYINDEX, addMe.getCity());
			
			addMe.setAirportID(runInsertPrepAndGetKey(addAirportStatement, findAirportKeyStatement));
			
			airports.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	public Seat addSeat(Seat addMe) throws Exception {
		int curIndex = seats.indexOf(addMe);
		
		if(curIndex != -1) {
			return seats.get(curIndex);
		}
		
		if(!addMe.getReservation().isIdSet() || !addMe.getPassenger().isIdSet() || 
				!addMe.getFlightDate().isIdSet()) {
			throw new Exception("Id not set on required field");
		}
		
		try{
			updateSeatStatement.setInt(SEATROWINDEX, addMe.getSeatRow());
			updateSeatStatement.setInt(SEATCOLINDEX, addMe.getSeatCol());
			
			updateSeatStatement.setInt(RESERVATIONIDINDEX, (int)addMe.getReservation().getReservationID());
			updateSeatStatement.setInt(PASSENGERIDINDEX, (int)addMe.getPassenger().getPassengerID());
			updateSeatStatement.setInt(FLIGHTDATEIDINDEX, (int)addMe.getFlightDate().getFlightDateID());
			
			updateSeatStatement.executeUpdate();
			
			seats.add(addMe);
			
		}catch (SQLException ex) {
			
			ex.printStackTrace();
		}
		
		return addMe;
	}
	
	/**
	 * Runs the prepared statement and returns the generated key
	 * @param stat the prepared statement to run, should be an insert statement
	 * @return the key created by the insert
	 * @throws SQLException if a database error occurs
	 */
	private int runInsertPrepAndGetKey(PreparedStatement stat, PreparedStatement readKey) throws SQLException {
		
		int key = -1;
		
		stat.executeUpdate();
		
		ResultSet rs = readKey.executeQuery();
		if ( rs.next() ) {
		    // Retrieve the auto generated key(s).
		    key = rs.getInt(1);
		}
		
		return key;
	}
	
	public Employee getEmployeeFromFirstAndLastName(String firstName, String lastName) {
		
		int curIndex = employees.indexOf(new Employee(firstName,lastName,true,true));
		
		if(curIndex == -1) {
			curIndex = employees.indexOf(new Employee(firstName,lastName,false,true));
			
			if(curIndex == -1) {
				return null;
			}
		}
		
		return employees.get(curIndex);
	}
	
	public FlightSegment getFlightSegmentFromFlightNoAndAirlineCode(String flightNo, String airCode) {
		
		int curIndex = flightSegments.indexOf(new FlightSegment(flightNo, new Airline(airCode)));
		
		if(curIndex == -1) {
			return null;
		}
		
		return flightSegments.get(curIndex);
	}
	
	public FlightDate getFlightDateFromFSAndDate(FlightSegment fs, Date departureDate) {
		int curIndex = flightDates.indexOf(new FlightDate(fs,departureDate));
		
		if(curIndex == -1) {
			return null;
		}
		
		return flightDates.get(curIndex);
	}
	
	public void commitAndClose(){
		try{
			conn.commit();
			if(!conn.isClosed()) conn.close();
		}catch (SQLException ex){
			ex.printStackTrace();
		}
	}
	
}

